﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using QxFramework.Core;
public class CombinableItem : Item
{
    public CombinableItemField Setting;
    [HideInInspector]
    public List<ItemFunc> FuncList = new List<ItemFunc>();
    protected ItemPhysic physic;

    public override ItemField ItemFieldSetting { get => Setting; set => Setting = (CombinableItemField)value; }

    public override Sprite Sprite => sprite.GetComponent<SpriteRenderer>().sprite;
/// <summary>
/// 设置有关刚体的信息
/// </summary>
/// <param name="rigid"></param>
/// <returns>物体内含刚体所分配的质量</returns>
    public virtual float SetRigidInfo(Rigidbody2D rigid)
    {
        physic.Rigid = rigid;
        //获取子物体中的刚体,将质量均匀分配在子物体上
        var coliiders = this.GetComponentsInChildren<Collider2D>();

        float area = 0;
        var rigids = this.GetComponentsInChildren<Rigidbody2D>();
        if (rigids.Length == 0)
        {
            foreach(var x in coliiders)
            {
                area += x.GetArea();
            }
            foreach(var x in coliiders)
            {
                    x.density = ItemFieldSetting.Mass / area;
            }
            return 0;
        }
        else
        {
            collider.GetComponent<Collider2D>().attachedRigidbody.useAutoMass = true;
            foreach (var x in coliiders)
            {
                if (x.attachedRigidbody != collider.GetComponent<Collider2D>().attachedRigidbody)
                {
                    x.attachedRigidbody.useAutoMass = true;
                    area += x.GetArea();
                }
            }
            foreach (var x in coliiders)
            {
                if (x.attachedRigidbody != collider.GetComponent<Collider2D>().attachedRigidbody)
                {
                    x.density = ItemFieldSetting.Mass / area;
                }
            }
            foreach(var x in rigids)
            {
                x.useAutoMass = true;
            }
            return ItemFieldSetting.Mass;
        }
        float subMass = 0;
        foreach(var x in rigids)
        {
            x.useAutoMass = true;
         //   x.mass = 0;
            subMass += x.mass;
        }
        return subMass;
    }
    public override ItemField UploadInstanceField()
    {
        ItemFieldSetting = base.UploadInstanceField();
        (ItemFieldSetting as CombinableItemField).PhysicTransform = physic.PhysicTransform;
        //      Debug.Log(Setting.ItemName + " ___________" + Setting.PhysicTransform.Angle);
    /*    if (needUpdateLocalRotation)
        {
            if (collider.transform.localScale.x < 0)
            {
                (ItemFieldSetting as CombinableItemField).MeshTransform.IsFliped = true;
            }
            else
            {
                (ItemFieldSetting as CombinableItemField).MeshTransform.IsFliped = false;
            }
        }
        (ItemFieldSetting as CombinableItemField).MeshTransform.LocalRotate = LocalRotationInDegree;*/
        //return UnsafeTool.DeepCopy<CombinableItemField>(Setting);
        //Debug.Log(this+" "+Setting.PhysicTransform.Angle);
        return ItemFieldSetting ;
    }
    protected GameObject sprite;
    protected GameObject collider;
    public  Vector3 GetLocalDirection( float dir)
    {
        if (collider == null)
        {
            collider = this.transform.Find("Collider").gameObject;
        }
   //     Debug.Log(collider.transform.up);
        return transform.InverseTransformPoint(collider.transform.position + Mathf.Cos(dir / 180f * Mathf.PI) * collider.transform.up + Mathf.Sin(dir / 180f * Mathf.PI) * (-collider.transform.right)*((ItemFieldSetting as CombinableItemField).IsFliped?-1:1));
        if (dir == 0)
        {
            return transform.InverseTransformPoint(collider.transform.position + collider.transform.up);
        }
        else if (dir == 1)
        {
            return transform.InverseTransformPoint(collider.transform.position - collider.transform.right);
        }
        else if (dir == 2)
        {
            return transform.InverseTransformPoint(collider.transform.position - collider.transform.up);
        }
        else
        {
            return transform.InverseTransformPoint(collider.transform.position + collider.transform.right);
        }
    }
    public Vector3 GetWorldDirection(float dir)
    {
        //   dir += field.Setting.MeshTransform.MeshRotate;
        //  dir %= 4;
        return transform.TransformPoint(GetLocalDirection(dir)) - transform.position;
    }


    /*void UpdateRotation(ItemMeshTransform trans)
    {
        var scale = sprite.transform.localScale;
        if (trans.IsFliped)
        {
            scale.x = Mathf.Abs(scale.x) * -1;
        }
        else
        {
            scale.x = Mathf.Abs(scale.x);
        }
        LocalRotationInDegree = trans.LocalRotate;
       // sprite.transform.localEulerAngles = collider.transform.localEulerAngles = new Vector3(0, 0, trans.MeshRotate);
        sprite.transform.localScale = collider.transform.localScale = scale;

        sprite.transform.localPosition = collider.transform.localPosition = Vector3.zero;

        this.transform.eulerAngles = Vector3.zero;
    }*/
    public override void DownloadInstanceField(object args)
    {
        base.DownloadInstanceField(args);
        var tp = args as CombinableItemField;
        ItemFieldSetting= tp;
        /*if (needUpdateRotation)
        {
            UpdateRotation((ItemFieldSetting as CombinableItemField).MeshTransform);

        }*/
        physic.UpdatePhysic((ItemFieldSetting as CombinableItemField).PhysicTransform);

       /* if (Setting.MeshTransform.IsFliped)
        {
            var scale = this.transform.localScale;
            scale.x =Mathf.Abs(scale.x)* -1;
            this.transform.localScale = scale;
        }*/
      //  this.GetComponent<Rigidbody2D>().mass = Setting.Mass;
      //  Debug.Log(this+" "+Setting.PhysicTransform.Position+" "+Setting.PhysicTransform.Angle);
       // throw new System.NotImplementedException();
    }
    public override void OnPreferenceDestory()
    {
        base.OnPreferenceDestory();
        var rigid = this.transform.parent;
        this.transform.SetParent(null);
        rigid.GetComponent<ItemRigid>().SetRigidInfo();
    }

    public override void OnDamage(float damage)
    {
        base.OnDamage(damage);
        MessageManager.Instance.Get<CameraController.CameraFollowType>().DispatchMessage(CameraController.CameraFollowType.Shake, this, new CameraController.CameraFollowArgs
        {
            player = this,
            pos =default

        });
    }
    private void OnDrawGizmos()
    {
        for(int i = 0; i < 4; i++)
        {
            if ((((ItemFieldSetting as CombinableItemField).ConnectState & (1<<i)) != 0))
            {
                //var fx = Item.GetLocalDirection(field, dir);
                Gizmos.DrawWireCube(this.transform.position+GetWorldDirection(i*90f)*GameMap.MapManager.itemSize/2.25f, Vector3.one * 0.2f);
            }
        }
    }
    public override void OnAwake()
    {
        base.OnAwake();
        physic = this.gameObject.AddComponent<ItemPhysic>();
        sprite = this.transform.Find("Sprite").gameObject;
        collider = this.transform.Find("Collider").gameObject;

        FuncList = new List<ItemFunc>(GetComponentsInChildren<ItemFunc>());
    }
    public override void OnStart()
    {

    }
}
[System.Serializable]
public class CombinableItemField : ItemField
{
    public int ConnectState;
    [HideInInspector]
    public ItemBelongingType BelongingType;
    public ItemPhysicTransform PhysicTransform;
    public ItemMeshTransform MeshTransform;
    public bool IsPlayer = false;
    public virtual void ClearWhenToBench()
    {

    }
    public virtual void SetWhenToMap()
    {
        Rotation = MeshTransform.MeshRotate * 90;
        IsFliped = MeshTransform.IsFlipedInMesh;
    }
}

